﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace EncryptNotesAddIn
{
    public partial class EnterPasswordForm : Form
    {
        public string Password { get; set; }

        private List<char> UpperCaseCharacters;
        private List<char> LowerCaseCharacters;
        private List<char> NumberCharacters;
        private List<char> PunctuationCharacters;

        public EnterPasswordForm()
        {
            InitializeComponent();
        }

        private void PasswordTextBox_TextChanged(object sender, EventArgs e)
        {
            string password = PasswordTextBox.Text;
            ShowPasswordStrengthLabel(password);
        }
        private void ShowPasswordStrengthLabel(string password)
        {
            int score = GetPasswordStrengthScore(password);
            Color labelColor = Color.Red;
            string labelText = "(unacceptable)";

            if (score > 0 && score < 3) labelText = "(very weak)";

            if (score >= 3 && score < 6)
            {
                labelColor = Color.Purple;
                labelText = "(weak)";
            }

            if (score >= 6 && score < 8)
            {
                labelColor = Color.Brown;
                labelText = "(acceptable)";
            }

            if (score >= 8 && score < 11)
            {
                labelColor = Color.Green;
                labelText = "(strong)";
            }

            if (score >= 11)
            {
                labelColor = Color.Green;
                labelText = "(very strong)";
            }

            PasswordStrengthLabel.ForeColor = labelColor;
            PasswordStrengthLabel.Text = labelText;

        }

        /// <summary>
        /// Gets the password strength score.
        /// Max Score = 13. Min Score = 0
        /// </summary>
        /// <param name="password">The password.</param>
        /// <returns>the score</returns>
        private int GetPasswordStrengthScore(string password)
        {
            int score = 0;

            if (UpperCaseCharacters == null) FillUpperCaseCharacters();
            if (LowerCaseCharacters == null) FillLowerCaseCharacters();
            if (NumberCharacters == null) FillNumberCharacters();
            if (PunctuationCharacters == null) FillPunctuationCharacters();

            //score password length
            if (password.Length >= 3 && password.Length < 6) score += 1;
            if (password.Length >= 6 && password.Length < 8) score += 2;
            if (password.Length >= 8 && password.Length < 10) score += 3;
            if (password.Length >= 10) score += 4;

            char[] passwordChars = password.ToCharArray();

            //check for lower case characters
            if (passwordChars.Intersect(LowerCaseCharacters).Count() > 0) score += 1;

            //score upper case characters
            if (passwordChars.Intersect(UpperCaseCharacters).Count() > 0) score += 2;

            //score numbers
            if (passwordChars.Intersect(NumberCharacters).Count() > 0) score += 3;

            //score numbers
            if (passwordChars.Intersect(PunctuationCharacters).Count() > 0) score += 3;
            
            return score;
        }
        private void FillUpperCaseCharacters()
        {
            UpperCaseCharacters = new List<char>();
            for (int i = 65; i < 90; i++) UpperCaseCharacters.Add(((char)i));
        }
        private void FillLowerCaseCharacters()
        {
            LowerCaseCharacters = new List<char>();
            for (int i = 97; i < 122; i++) LowerCaseCharacters.Add(((char)i));
        }
        private void FillNumberCharacters()
        {
            NumberCharacters = new List<char>();
            for (int i = 48; i < 57; i++) NumberCharacters.Add(((char)i));
        }
        private void FillPunctuationCharacters()
        {
            PunctuationCharacters = new List<char>();
            for (int i = 32; i < 47; i++) PunctuationCharacters.Add(((char)i));
            for (int i = 58; i < 64; i++) PunctuationCharacters.Add(((char)i));
            for (int i = 91; i < 96; i++) PunctuationCharacters.Add(((char)i));
            for (int i = 123; i < 126; i++) PunctuationCharacters.Add(((char)i));
        }

        private void OkButton_Click(object sender, EventArgs e)
        {
            if (PasswordStrengthLabel.Text == "(unacceptable)")
            {
                MessageBox.Show("This password is unacceptably weak.");
                return;
            }

            if (PasswordStrengthLabel.Text == "(very weak)" || PasswordStrengthLabel.Text == "(weak)")
            {
                DialogResult result = MessageBox.Show("This password is not very complex and could be easily guessed. Are you sure you want to continue?", "Weak Password Warning", 
                    MessageBoxButtons.OKCancel);
                if (result == DialogResult.Cancel) return;
            }


            this.Password = PasswordTextBox.Text;
            this.Hide();
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            this.Password = string.Empty;
            this.Hide();
        }

        public void ClearPassword()
        {
            PasswordTextBox.Text = string.Empty;
            this.Password = string.Empty;
            GetPasswordStrengthScore(string.Empty);
        }

        private void EnterPasswordForm_Load(object sender, EventArgs e)
        {
            PasswordTextBox.Focus();
        }
    }
}
